package dbutils

import (
	"database/sql"
	"fmt"
	"log"
)

// CheckTablesExist 检查指定数据库中是否存在超过三个表。
//
// 参数:
// - db: 指向 sql.DB 对象的指针，表示数据库连接。
// - dbName: 字符串，指定要检查的数据库名称。
//
// 返回值:
//   - bool: 如果指定数据库中的表数量大于三，则返回 true，否则返回 false。
//   - error: 错误对象，用于指示查询执行过程中是否发生问题。
//     如果查询失败或扫描结果出错，将返回包含详细信息的错误。
func CheckTablesExist(db *sql.DB, dbName string) (bool, error) {
	// 查询以统计指定数据库模式中的表数量。
	query := `SELECT COUNT(*) FROM information_schema.tables 
	WHERE table_schema = ?`
	var count int

	// 执行查询并将结果扫描到 count 变量中。
	err := db.QueryRow(query, dbName).Scan(&count)
	if err != nil {
		// 如果查询执行失败或扫描失败，返回错误。
		return false, fmt.Errorf("检查表的查询失败: %v", err)
	}

	// 如果表的数量大于 3，返回 true，否则返回 false。
	return count > 3, nil
}

// ConnectDB 建立与 MySQL 数据库的连接，使用提供的凭据和连接参数。
// 参数:
//   - user: 用于数据库认证的用户名。
//   - password: 指定用户的密码。
//   - host: 数据库服务器的主机名或 IP 地址。
//   - port: 数据库服务器监听的端口号。
//   - dbname: 要连接的数据库名称。
//
// 返回值:
//   - *sql.DB: 表示已建立数据库连接的 sql.DB 对象指针。
//   - error: 错误对象，用于指示连接是否失败，并在失败时提供详细信息。
func ConnectDB(user, password, host string, port int, dbname string) (*sql.DB, error) {
	// 构造数据库连接所需的 Data Source Name (DSN)。
	dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?multiStatements=true", user, password, host, port, dbname)

	// 尝试使用构造的 DSN 打开与数据库的连接。
	db, err := sql.Open("mysql", dsn)
	if err != nil {
		fmt.Println(dsn)
		// 如果连接失败，返回带有描述性信息的错误。
		return nil, fmt.Errorf("无法连接到数据库: %v", err)
	}

	// 通过 Ping 验证连接。如果 Ping 失败，记录致命错误。
	if err = db.Ping(); err != nil {
		fmt.Println(dsn)
		log.Fatal("数据库连接验证失败:", err)
	}

	// 返回成功建立的数据库连接。
	return db, nil
}
